home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * Aux Handler V1.0 (c)Copyright 1987,1989 Steve Drew. All Rights Reserved.
- *
- * Aux-Handler Ver. 1.2 21-Dec-1989
- *
- * Steve Drew
- * 216 MacEwan Valley Mews N.W.
- * Calgary, Ab. Canada.
- *
- * |You may freely distribute this source as long as |
- * |the Copyright notice is left intact. |
- *
- * Not for commercial use, unless approved by the author.
- ***************************************************************************/
- /*
- * Ver. 1.1 19-Oct-1989
- *
- * - Modified not to ignore null character when in RAW mode.
- * - slightly modified read_ser() to ensure all console style handling
- * is ignored in raw mode.
- * - Added support for my AuxZmodem program (AZ). AZ sends AUX: an inhibit
- * dos packet. AUX then cancels any reads to Serial port until AZ completes.
- *
- * Ver. 1.2 21-Dec-1989
- *
- * - don't have aux process hang around if SER: not available
- * - fix sec/micros in waitforchar()
- * - added carrier detection, if carrier disappears (was previously present )
- * then throw away output, until carrier returns.
- *
- * ver 1.2a, 22-Apr-1992 did setparams to ensure XON/XOFF enabled.
- *
- * Ver 1.3 04-May-1992, added support for multi line cards.
- * Ver 1.3a still trying to get multiline cards to work
- * Ver 1.3b force XON flow control enabled.
- * Ver 3.42L23 Setup for SAS/C and for use with Citadel
- * Ver 3.42P15 Setup the serial port access like Citadel's
- * so the GVP IOExtender would work... Also added a
- * Debug Port option...
- */
- #include "string.h"
- #include <libraries/dos.h>
- /*#include <ctype.h>*/
- #include <devices/console.h>
- #include <devices/serial.h>
- #include <devices/timer.h>
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/memory.h>
- #include <exec/tasks.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/libraries.h>
- #include <exec/devices.h>
- #include <exec/io.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/filehandler.h>
- #include "proto/all.h"
- #include "pragmas/dos_pragmas.h"
- #include "pragmas/exec_pragmas.h"
- #include "aux-debug.h"
-
- int atoi(char *);
- void _main(char *);
- void chk_params ( char *str );
- void chk_pend ( char *buf , struct DosPacket *pkt , struct Process *proc );
- int read_ser ( char *buf );
- void do_echo ( char *buf );
- void set_read( void );
- void write_ser ( char *buf , int len );
- void puts_ser ( char *buf , int len );
- int is_carrier ( void );
- int open_devices ( void );
- int open_serial ( void );
- int open_timer ( void );
- void close_devices ( void );
- void parse_startup ( char *str );
- void Aux_Debug(char *, int, int, int, int);
- void returnpktplain ( struct DosPacket *packet , struct Process *myproc );
- void returnpkt ( struct DosPacket *packet , struct Process *myproc , ULONG res1 , ULONG res2 );
- struct DosPacket *taskwait ( struct Process *myproc );
-
- struct DosLibrary *DOSBase;
- struct DosLibrary *SYSBase;
-
- #define DEVICE_NUMBER 0 /* serial device unit number to use */
- #define DEVICE_NAME "serial.device" /* drive name for device */
- typedef unsigned char u_char;
- #undef BADDR
- #define BADDR(x) ((APTR)((long)x << 2))
- #define AUX_ECHO 1
- #define AUX_CRLF 2
- #define AUX_RAW 4
- #define AUX_RPEND 8
- #define AUX_WAIT_FOR 16
- #define AUX_TYPEAHEAD_FULL 32
- #define AUX_SER_QUEUED 64
- #define AUX_MODEM 128
- #define DOECHO (aux_stat & AUX_ECHO)
- #define DOCRLF (aux_stat & AUX_CRLF)
- #define ISRAW (aux_stat & AUX_RAW)
- #define ISRPEND (aux_stat & AUX_RPEND)
- #define ISWAITING (aux_stat & AUX_WAIT_FOR)
- #define ISBUFFULL (aux_stat & AUX_TYPEAHEAD_FULL)
- #define READINPROGRESS (aux_stat & AUX_SER_QUEUED)
- #define ISMODEM (aux_stat & AUX_MODEM)
- #define AUXBUFSIZE 256 /* Same as CON: handler */
- #define MAXLINESIZE 254 /* save two for \n'\0' */
- #define MYPORT_SIG (1L << myport->mp_SigBit)
- #define READSER_SIG (1L << ReadSER->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
- #define TIMER_SIG (1L << Timer_Port->mp_SigBit)
- /* My Globals */
-
- struct MsgPort *mySerReadPort = NULL;
- struct MsgPort *mySerWritePort = NULL;
- struct IOExtSer *ReadSER = NULL;
- struct IOExtSer *WriteSER = NULL;
-
-
- struct timerequest *Timer;
- struct MsgPort *Timer_Port;
- struct Task *reader;
- int aux_stat, aux_avail, in_len;
- u_char in_c;
- long device_number;
- char *device_name;
- long device_baud;
- char *version = "\0$VER: Citadel Aux Handler 3.42P15 (12.30.93)";
- void _main(arg)
- char *arg; /* default parameter */
- {
- struct Process *myproc; /* my process */
- struct DosPacket *mypkt; /* a pointer to the dos packet */
- struct DosPacket *rdpkt;
- struct DeviceNode *mynode; /* our device node (parmpkt Arg3) */
- struct FileHandle *fh; /* a pointer to our file handle */
- struct MsgPort *myport;
- long run = TRUE; /* handler main loop flag */
- u_char *ptr; /* ptr for name translation */
- char *name,*s; /* ptr to name for open */
- int aux_open = 0; /* aux open count */
- char auxbuf[AUXBUFSIZE];/* Our type ahead buffer */
- ULONG signals; /* signals that occurred in Wait */
- char startup[100];
- /* Initializing the handler */
- DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0L);
- SYSBase = (struct DosLibrary *)OpenLibrary("exec.library", 0L);
- myproc = (struct Process *)FindTask(0L);
- Aux_Debug("Startup Message Wait...", (int)myproc, aux_stat, 0,FALSE);
- mypkt = taskwait(myproc); /* Wait for my startup message */
- rdpkt = mypkt;
- mynode = (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
- mynode->dn_Task = &myproc->pr_MsgPort;
- myport = &myproc->pr_MsgPort;
- returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
- in_len = aux_avail = aux_stat = 0;
- reader = (struct Task *) 0;
- s = (char *)BADDR(mypkt->dp_Arg2) ; /* Arg2= BSTR to mountlist Startup */
- if( s != NULL )
- {
- strncpy(startup,s+1,s[0]);
- startup[s[0]] = '\0';
- s = startup;
- if (*s == '\"')
- {
- s++;
- s[strlen(s)-1]= '\0' ;
- };
- }
- else startup[0] = '\0';
- /* set defaults */
- device_name = DEVICE_NAME;
- device_number = DEVICE_NUMBER;
- device_baud = 0;
- parse_startup(s);
- /* done initial stuff, now for some work */
- Aux_Debug(device_name, device_number, device_baud, 0,FALSE);
- while(run)
- {
- if (aux_open)
- {
- /* then wait for read char or new action */
- if (READINPROGRESS)
- signals = Wait( MYPORT_SIG | READSER_SIG | TIMER_SIG );
- else
- signals = Wait( MYPORT_SIG );
- if (signals & TIMER_SIG)
- {
- WaitIO((struct IORequest *)Timer);
- Aux_Debug("Timer SIG...", signals, aux_stat, 0,FALSE );
- aux_stat &= ~AUX_WAIT_FOR;
- rdpkt->dp_Res1 = DOSFALSE;
- returnpktplain(rdpkt,myproc);
-
- }
- if ((signals & READSER_SIG) && CheckIO((struct IORequest *)ReadSER))
- {
- Aux_Debug("READSER SIG...", signals, aux_stat, 0,FALSE);
- read_ser(auxbuf);
- chk_pend(auxbuf,rdpkt,myproc);
-
- }
- if (signals & MYPORT_SIG)
- {
- Aux_Debug("MYPORT_SIG...",signals,aux_stat,0,FALSE);
- mypkt = taskwait(myproc);
-
- }
- else /* no new dospackets */
- continue;
-
- }
- else /* only port at the moment is myport */
- mypkt = taskwait(myproc);
- Aux_Debug("dp_type...", signals, (int)mypkt, (int)mypkt->dp_Type,FALSE);
- switch(mypkt->dp_Type)
- {
- /* find what action to perform */
- case MODE_OLDFILE:
- case MODE_NEWFILE:
- /*
- I allow for multiple writers. But only one process to read
- at a time.
- */
- if (!aux_open)
- {
- /* first time here we open the devices */
- if (open_devices() == 0)
- {
- Aux_Debug("Error... open_device failed", 0, 0, 0,FALSE);
- returnpkt(mypkt, myproc, DOSFALSE, ERROR_OBJECT_IN_USE);
- run = 0; /* don't hang arround */
- break;
-
- }
-
- }
- aux_open++;
- /*
- * if baud specified in Startup message, set it here, else
- * check filename for SET/ param later below.
- */
- /* xxx */
- /* get file name and Upper case it */
- ptr = (u_char *)BADDR(mypkt->dp_Arg3);
- name = (char *)AllocMem((long)*ptr + 1, MEMF_PUBLIC);
- movmem(ptr+1, name, *ptr);
- name[*ptr] = '\0';
- for (s = name; *s; ++s)
- {
- *s = (*s >= 'a' && *s <= 'z') ? (*s - 'a' + 'A') : *s;
- };
- /*
- This is a Hack to allow a bail out of a NEWCLI
- that is using the AUX. By doing say an echo >AUX:ENDCLI
- from another process the reader (being the NEWCLI)
- will be sent a ENDCLI command.
- */
- Aux_Debug(name, ISRPEND, aux_stat, 0,FALSE);
- for (s = name; *s; ++s) if (*s == ':') break;
- if (!strcmp(s,":ENDCLI") && (ISRPEND))
- {
- strcpy((char *)rdpkt->dp_Arg2,"ENDCLI\n");
- rdpkt->dp_Res1 = 7L;
- returnpktplain(rdpkt, myproc);
- aux_stat &= ~AUX_RPEND;
-
- }
- else
- chk_params(name);
- FreeMem(name, (long)*ptr +1);
- fh = (struct FileHandle *)BADDR(mypkt->dp_Arg1);
- fh->fh_Arg1 = DOSTRUE;
- fh->fh_Port = (struct MsgPort *)DOSTRUE;
- if (mypkt->dp_Type == MODE_OLDFILE)
- {
- struct MsgPort *port;
- port = mypkt->dp_Port;
- if (reader && port->mp_SigTask != reader)
- {
- returnpkt(mypkt, myproc, DOSFALSE, ERROR_OBJECT_IN_USE);
- --aux_open;
- break;
-
- }
- reader = port->mp_SigTask;
- fh->fh_Arg1 = (long)port->mp_SigTask;
-
- }
- returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
- break;
- case ACTION_READ:
- set_read();
- rdpkt = mypkt;
- aux_stat |= AUX_RPEND;
- do_echo(auxbuf);
- chk_pend(auxbuf,rdpkt,myproc);
- Aux_Debug("ACTION_READ", 0, aux_stat, 0,FALSE);
- break;
- case ACTION_WRITE:
- write_ser((char *)mypkt->dp_Arg2,(int)mypkt->dp_Arg3);
- mypkt->dp_Res1 = mypkt->dp_Arg3; /* tell em we wrote them all */
- returnpktplain(mypkt, myproc);
- Aux_Debug("ACTION_WRITE", 0, aux_stat, 0,FALSE);
- break;
- case ACTION_WAIT_CHAR:
- /* just queue up to wait for data */
- set_read();
- rdpkt = mypkt;
- aux_stat |= AUX_WAIT_FOR;
- if (rdpkt->dp_Arg1 >= 1000000L)
- {
- Timer->tr_time.tv_secs = rdpkt->dp_Arg1 / 1000000L;
- Timer->tr_time.tv_micro = rdpkt->dp_Arg1 % 1000000L;
-
- }
- else
- {
- Timer->tr_time.tv_secs = 0L;
- Timer->tr_time.tv_micro = rdpkt->dp_Arg1;
-
- }
- SendIO((struct IORequest *)Timer);
- chk_pend(auxbuf,rdpkt,myproc);
- Aux_Debug("ACTION_WAIT_CHAR", 0, aux_stat, 0,FALSE);
- break;
- case ACTION_SCREEN_MODE:
- if (mypkt->dp_Arg1)
- {
- aux_stat |= AUX_RAW;
- aux_stat &= ~AUX_ECHO;
-
- }
- else
- {
- aux_stat &= ~AUX_RAW;
- aux_stat |= AUX_ECHO;
-
- }
- chk_pend(auxbuf,rdpkt,myproc);
- returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
- Aux_Debug("ACTION_SCREEN_MODE", 0, aux_stat, 0,FALSE);
- break;
- case ACTION_END:
- if (--aux_open == 0)
- {
- run = 0;
- close_devices();
- reader = (struct Task *) 0L;
-
- }
- returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
- Aux_Debug("ACTION_END", 0, aux_stat, 0,FALSE);
- break;
- case ACTION_INHIBIT:
- if (READINPROGRESS)
- {
- AbortIO((struct IORequest *)ReadSER);
- Wait(READSER_SIG);
- WaitIO((struct IORequest *)ReadSER);
- aux_stat &= ~AUX_SER_QUEUED;
-
- }
- returnpkt(mypkt, myproc, DOSTRUE, mypkt->dp_Res2);
- Aux_Debug("ACTION_INHIBIT", 0, aux_stat, 0,FALSE);
- break;
- default:
- returnpkt(mypkt, myproc, DOSFALSE, ERROR_ACTION_NOT_KNOWN);
- Aux_Debug("Default...", 0, aux_stat, 0,FALSE);
- break;
-
- }
-
- }
- /* end while */
- mynode->dn_Task = FALSE;
- CloseLibrary((struct Library *)DOSBase);
- CloseLibrary((struct Library *)SYSBase);
- }
- /*
- Allows some flexibilty to control the port.
- Can dynamically change CRLF translation,
- Echo or RAW mode on/off.
- */
- void chk_params(str)
- char *str;
- {
- char *ptr, *s;
- int param, i=1;
- Aux_Debug(str, 0, 0, 0,TRUE);
- for (s = str; *s; ++s) if (*s == ':') break;
- if (strncmp(str,":SET/",5)) return;
- ptr = str + 8;
- while(i)
- {
- for (s = ptr; *ptr && *ptr != '/'; ++ptr);
- if (*ptr == '\0') i = 0;
- *ptr = '\0';
- str = s+2;
- if (ptr > str)
- {
- switch (*s)
- {
- case 'E':
- param = AUX_ECHO;
- break;
- case 'C':
- param = AUX_CRLF;
- break;
- case 'R':
- param = AUX_RAW;
- break;
- default:
- param = 0;
- break;
-
- }
- if (*str == 'O')
- {
- if (*(str+1) == 'N') aux_stat |= param;
- else
- if (*(str+1) == 'F') aux_stat &= ~param;
-
- }
-
- }
- ++ptr;
-
- }
-
- }
- /*
- Check our buf to see if we have a line to return yet. Or if raw mode
- give 'em all we got.
- */
- void chk_pend(buf,pkt,proc)
- char *buf;
- struct DosPacket *pkt;
- struct Process *proc;
- {
- char *p;
- int i=0;
- Aux_Debug("chk_pend",in_len, aux_stat, aux_avail,FALSE);
- if ((in_len && (ISRAW)) || aux_avail)
- {
- if (ISWAITING)
- {
- aux_stat &= ~AUX_WAIT_FOR; /* clear the wait_for */
- pkt->dp_Res1 = DOSTRUE;
- AbortIO((struct IORequest *)Timer);
- Wait(TIMER_SIG);
- WaitIO((struct IORequest *)Timer);
- returnpktplain(pkt,proc);
-
- }
- else if (ISRPEND)
- {
- aux_stat &= ~AUX_RPEND; /* clear the pending read */
- if (ISRAW)
- {
- aux_avail = 0; /* since we're sending all */
-
- }
- else
- --aux_avail;
- /* if in_len is zero, then aux_avail must of been
- set up to force us here to reply with Res1 = 0;
- thus actually returning an EOF.
- */
- if (in_len)
- {
- for (i = 1,p = (char *) pkt->dp_Arg2;
- ((p[i-1] = buf[i-1]) != '\n' || ISRAW) &&
- i < pkt->dp_Arg3 && i < in_len; ++i) ;
- /* reader asked for less than 256 chars but no cr
- was found. If not in raw mode then bump avail back
- up since we still have the remaining CR terminated
- line in buf[].
- */
- if (p[i-1] != '\n' && !(ISRAW))
- {
- ++aux_avail;
-
- }
-
- }
- in_len -= i;
- movmem(buf+i,buf,in_len);
- set_read();
- pkt->dp_Res1 = (long)i;
- Aux_Debug(buf,in_len, aux_stat, aux_avail,TRUE);
- returnpktplain(pkt,proc);
-
- }
-
- }
-
- }
- /*
- Only called here if there really is a character waiting to be read.
- */
- read_ser(buf)
- char *buf;
- {
- char c;
- int ignore = 1;
- if( ReadSER == NULL )
- {
- if( reader )Signal(reader, SIGBREAKF_CTRL_C);
- return 1;
- };
- Aux_Debug("read_ser before", in_c, aux_stat, ReadSER->IOSer.io_Error,FALSE);
- WaitIO((struct IORequest *)ReadSER);
- aux_stat &= ~AUX_SER_QUEUED;
- c = in_c;
- Aux_Debug("read_ser after", c, aux_stat, ReadSER->IOSer.io_Error,FALSE);
- /* ^C typed so immediately send the signal */
- if (c == 3)
- {
- if (reader)
- Signal(reader,SIGBREAKF_CTRL_C);
-
- }
- /*
- * in raw mode, no filtering is done.
- */
- if (ISRAW)
- {
- if (in_len < MAXLINESIZE) buf[in_len++] = c;
- set_read();
- return(1);
-
- }
- switch(c)
- {
- case 3: /* already done above */
- break;
- case 4: /* ^D, send the signal if there is a reader */
- if (reader)
- Signal(reader,SIGBREAKF_CTRL_D);
- break;
- case 6: /* ^F, send the signal if there is a reader */
- if (reader)
- Signal(reader,SIGBREAKF_CTRL_F);
- break;
- case 28: /* ^\ so wipe out line and force EOF */
- in_len = 0;
- ++aux_avail;
- break;
- case 13: /* Always convert ^M to newline chara */
- case 10:
- c = 10;
- ignore = 0;
- ++aux_avail;
- break;
- case 8: /* BS */
- case 127: /* DEL */
- if (in_len && buf[in_len-1] != '\n')
- {
- --in_len;
- write_ser("\b \b",3);
-
- }
- break;
- case 24: /* ^X */
- case 21: /* ^U */
- while(in_len && buf[in_len-1] != '\n')
- {
- --in_len;
- write_ser("\b \b",3);
-
- }
- break;
- case 18: /* ^R */
- if (ISRPEND)
- {
- write_ser("\n",1);
- do_echo(buf);
-
- }
- break;
- case 27: /* <ESC> */
- break;
- default:
- ignore = 0;
- break;
-
- }
- /*
- * is it, a valid character
- */
- if (ignore == 0)
- {
- /*
- * Length is already at maximum, forget about this character
- * and Beep the user.
- */
- if (c != '\n' && in_len >= MAXLINESIZE)
- {
- write_ser("\007",1);
-
- }
- /*
- * normal case, save and echo if applicable
- */
- else
- {
- buf[in_len++] = c;
- /*
- * don't echo unless aux process has caught upto us.
- * ie, simulate VMS terminal handler rather than unix or
- * amigados con:. This makes it nicer to typeahead the next
- * command without causing the output from the current command
- * to stop, thus pausing the current command.
- */
- if (DOECHO)
- {
- if (ISRPEND) write_ser(&c,1);
-
- }
-
- }
-
- }
- set_read();
-
- }
- /*
- * Now ready to echo first line of typeahead, or possible retyping
- * due to ^R command.
- */
- void do_echo(buf)
- char *buf;
- {
- int i;
- if (DOECHO)
- {
- for(i = 0; i < in_len ; ++i)
- {
- if (buf[i] == '\n')
- {
- ++i;
- break;
-
- }
-
- }
- if (i) write_ser(buf,i);
-
- }
-
- }
- /*
- Start a asynchronous Read request
- */
- void set_read()
- {
- Aux_Debug("set_read", in_c, aux_stat, READINPROGRESS,FALSE);
- if (!READINPROGRESS)
- {
- ReadSER->IOSer.io_Length = 1L;
- ReadSER->IOSer.io_Command = CMD_READ;
- ReadSER->IOSer.io_Data = (APTR) &in_c;
- SendIO((struct IORequest *)ReadSER);
- aux_stat |= AUX_SER_QUEUED;
-
- }
-
- }
- void write_ser(buf,len)
- char *buf;
- int len;
- {
- int i,j;
- Aux_Debug("write_ser", (int)buf, DOCRLF, len,FALSE);
- buf[len] = '\0';
- Aux_Debug(buf,len,0,0,TRUE);
- if (DOCRLF)
- {
- /*
- * rather than call the serial device for each character, write all
- * characters upto newline then insert <CR><LF> and continue.
- */
- for(j=i=0; i < len; ++i)
- {
- if (buf[i] == '\n')
- {
- puts_ser(&buf[j],(i-j));
- puts_ser("\r\n",2); /* ensure <CR><LF> order */
- j = i+1;
-
- }
-
- }
- if (j < len)
- puts_ser(&buf[j],(len-j));
-
- }
- else
- {
- puts_ser(buf,len);
-
- }
-
- }
- void puts_ser(buf,len)
- char *buf;
- int len;
- {
- /*
- * If carrier was present and now is'nt then discard characters until
- * carrier returns
- */
- if( WriteSER == NULL)return;
- Aux_Debug("puts_ser", (int)buf, ISMODEM, len,FALSE);
- if (len)
- {
- if (is_carrier() || !ISMODEM)
- {
- WriteSER->IOSer.io_Command = CMD_WRITE;
- WriteSER->IOSer.io_Length = (long)len;
- WriteSER->IOSer.io_Data = (APTR) buf;
- DoIO((struct IORequest *)WriteSER);
- Aux_Debug("puts_ser:result", buf[0],WriteSER->IOSer.io_Error, len,FALSE);
-
- }
-
- }
-
- }
- /*
- * return 0 if nocarrier
- */
- is_carrier()
- {
- if( WriteSER == NULL ) return (0);
- WriteSER->IOSer.io_Command = SDCMD_QUERY;
- DoIO((struct IORequest *)WriteSER);
- Aux_Debug("is_carrier", WriteSER->io_Status, aux_stat, WriteSER->IOSer.io_Error,FALSE);
- if (!(WriteSER->io_Status & 0x20))
- {
- aux_stat |= AUX_MODEM;
- return(1);
-
- }
- return(0);
-
- }
- open_devices()
- {
- ReadSER = WriteSER = NULL;
- Timer_Port = NULL;
- Timer = NULL;
- aux_stat = AUX_ECHO | AUX_CRLF; /* set the default */
- if (open_serial() && open_timer())
- {
- set_read();
- return(1);
-
- }
- close_devices();
- return(0);
-
- }
- /*
- * open serial device
- */
- open_serial()
- {
- if( (mySerReadPort = CreatePort(NULL,NULL)) != NULL)
- {
- Aux_Debug("open_serial",0 ,(int)mySerReadPort ,0 ,FALSE);
- ReadSER = (struct IOExtSer *)CreateExtIO(mySerReadPort, sizeof(struct IOExtSer));
- if( ReadSER != NULL )
- {
- Aux_Debug("open_serial",1 ,(int)ReadSER,0 ,FALSE);
- if( (mySerWritePort = CreatePort(NULL,NULL)) != NULL )
- {
- Aux_Debug("open_serial",2 ,(int)mySerWritePort,0 ,FALSE);
- WriteSER = (struct IOExtSer *)CreateExtIO(mySerWritePort, sizeof(struct IOExtSer));
- if( WriteSER != NULL)
- {
- ReadSER->io_SerFlags = SERF_RAD_BOOGIE|SERF_SHARED|SERF_XDISABLED|SERF_7WIRE;
- Aux_Debug("open_serial",3 ,(int)WriteSER,0 ,FALSE);
- if ( !OpenDevice(device_name,device_number,(struct IORequest*)ReadSER,NULL) )
- {
- WriteSER->io_SerFlags = SERF_RAD_BOOGIE|SERF_SHARED|SERF_XDISABLED|SERF_7WIRE;
- Aux_Debug("open_serial",4 ,(int)ReadSER->IOSer.io_Error,0 ,FALSE);
- if ( !OpenDevice(device_name,device_number,(struct IORequest *)WriteSER,NULL) )
- {
- Aux_Debug("open_serial",5 ,(int)WriteSER->IOSer.io_Error ,0 ,FALSE);
- return 1;
-
- }
- else
- {
- CloseDevice((struct IORequest *)ReadSER); /* extra thing to do if error */
-
- };
-
- };
-
- };
-
- };
-
- };
-
- };
- Aux_Debug("open_serial",-1 ,(int)mySerWritePort, (int)mySerReadPort ,FALSE);
- if( WriteSER )DeleteExtIO((struct IORequest *)WriteSER);
- if( mySerWritePort)DeletePort(mySerWritePort);
- if( ReadSER )DeleteExtIO((struct IORequest *)ReadSER);
- if( mySerReadPort )DeletePort(mySerReadPort);
- WriteSER = NULL;
- ReadSER = NULL;
- mySerWritePort = NULL;
- mySerReadPort = NULL;
- return(0);
-
- }
- /*
- * Open Timer.device
- */
- open_timer()
- {
- if (Timer_Port = CreatePort (NULL, NULL))
- {
- Aux_Debug("open_timer",0 ,0 ,0 ,FALSE);
- if ((Timer = (struct timerequest *)
- CreateExtIO (Timer_Port, (long) sizeof (*Timer))) != NULL )
- {
- Aux_Debug("open_timer",1 ,0 ,0 ,FALSE);
- if (!(OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *)Timer, 0L)))
- {
- Timer->tr_node.io_Command = TR_ADDREQUEST;
- Timer->tr_node.io_Flags = 0;
- Timer->tr_node.io_Error = 0;
- Aux_Debug("open_timer",2 ,0 ,0 ,FALSE);
- return(1);
-
- }
-
- }
-
- }
- Aux_Debug("open_timer",-1 ,(int)Timer_Port ,(int)Timer ,FALSE);
- Timer->tr_node.io_Device = 0;
- return(0);
-
- }
- void close_devices()
- {
- if (READINPROGRESS)
- {
- AbortIO((struct IORequest *)ReadSER);
- Wait(READSER_SIG);
- WaitIO((struct IORequest *)ReadSER);
-
- }
- if( ReadSER )
- {
- CloseDevice((struct IORequest *)ReadSER);
- DeleteExtIO((struct IORequest *)ReadSER);
-
- };
- if( mySerReadPort )DeletePort(mySerReadPort);
- if (WriteSER)
- {
- CloseDevice((struct IORequest *)WriteSER);
- DeleteExtIO((struct IORequest *)WriteSER);
-
- }
- if( mySerWritePort)DeletePort(mySerWritePort);
- if (Timer)
- {
- if (Timer->tr_node.io_Device)
- CloseDevice ((struct IORequest *)Timer);
- DeleteExtIO ((struct IORequest *)Timer);
-
- }
- WriteSER = NULL;
- ReadSER = NULL;
- mySerWritePort = NULL;
- mySerReadPort = NULL;
- if (Timer_Port)
- DeletePort(Timer_Port);
- Timer_Port = NULL;
- Aux_Debug("close_device",0 ,0 ,0 ,FALSE);
-
- }
- /*
- * in mountlist startup allow:
- *
- * startup = "DEVICE:serial.device/UNIT:0/BAUD:2400"
- */
- void parse_startup(str)
- char *str;
- {
- char *s = str;
- char *arg,*value;
- int more = 1;
- if( s == NULL)return;
- while(more)
- {
- for(arg = s; *s; ++s) if (*s == ':') break;
- if (!*s) break;
- *s = '\0';
- ++s;
- for(value = s; *s; ++s) if (*s == '/') break;
- if (!*s) more = 0;
- *s = '\0';
- ++s;
- if (strcmp("DEVICE",arg) == 0)
- {
- device_name = value;
-
- }
- else if (strcmp("UNIT",arg) == 0)
- {
- device_number = atoi(value);
-
- }
- else if (strcmp("BAUD",arg) == 0)
- {
- device_baud = atoi(arg);
-
- }
-
- }
-
- }
-
- void Aux_Debug(msg, int1, int2, int3, flag)
- char *msg; /* the message to send */
- int int1, int2, int3, flag; /* various integer data to send */
- {
- struct MsgPort *port;
- char *mymessage;
- struct debugmsg *temp;
- Forbid();
- port = FindPort(AUXDEBUGPORT); /* check to see if we have a port...*/
- Permit();
- if( !port )return; /* if no port, just exit */
- temp = (struct debugmsg *)AllocMem(sizeof(struct debugmsg),0);
- if(!temp) return;
- mymessage = (char *)AllocMem(strlen(msg)+1,0); /* dynamic sizing */
- if( mymessage == NULL)
- {
- FreeMem(temp, sizeof(struct debugmsg));
- return;
- };
- strcpy(mymessage,msg);
- temp->msg = mymessage;
- temp->a = int1;
- temp->b = int2;
- temp->c = int3;
- temp->flag = flag;
- /*
- ** Setup the Message itself
- */
- temp->ipc_Msg.mn_Node.ln_Type = NT_MESSAGE;
- temp->ipc_Msg.mn_Length = sizeof(struct debugmsg);
- temp->ipc_Msg.mn_ReplyPort = NULL;
-
- /* safe send of a message. If Port exists, we send the
- ** packet and forget about it. If the Port does not exist
- ** we forget that the message even existed...
- */
- Forbid();
- port = FindPort(AUXDEBUGPORT);
- if( port )
- {
- PutMsg(port,(struct Message *)temp);
- }
- else
- {
- FreeMem(temp->msg,strlen(msg)+1);
- FreeMem(temp, sizeof(struct debugmsg));
- }
- Permit();
- /*
- ** we do not wait for the message reply, in this case there is
- ** no reply done and all memmory is deallocated in the reciever.
- */
- }
- /* returnpkt() - packet support routine
- * here is the guy who sends the packet back to the sender...
- *
- * (I modeled this just like the BCPL routine [so its a little redundant] )
- */
-
- void returnpktplain(packet, myproc)
- struct DosPacket *packet;
- struct Process *myproc;
- {
- returnpkt(packet, myproc, packet->dp_Res1, packet->dp_Res2);
-
- }
- void
- returnpkt(packet, myproc, res1, res2)
- struct DosPacket *packet;
- struct Process *myproc;
- ULONG res1, res2;
- {
- struct Message *mess;
- struct MsgPort *replyport;
- packet->dp_Res1 = res1;
- packet->dp_Res2 = res2;
- replyport = packet->dp_Port;
- mess = packet->dp_Link;
- packet->dp_Port = &myproc->pr_MsgPort;
- mess->mn_Node.ln_Name = (char *) packet;
- mess->mn_Node.ln_Succ = NULL;
- mess->mn_Node.ln_Pred = NULL;
- PutMsg(replyport, mess);
- Aux_Debug("Return Packet",(int)packet ,res1 ,res2, FALSE );
-
- }
- /*
- * taskwait() ... Waits for a message to arrive at your port and
- * extracts the packet address which is returned to you.
- */
- struct DosPacket *
- taskwait(myproc)
- struct Process *myproc;
- {
- struct MsgPort *myport;
- struct Message *mymess;
- myport = &myproc->pr_MsgPort;
- WaitPort(myport);
- mymess = GetMsg(myport);
- Aux_Debug("taskwait",(int)mymess ,0 ,0, FALSE );
- return((struct DosPacket *)mymess->mn_Node.ln_Name);
-
- }
-